package org.wk.upms.service;

import com.google.common.base.Strings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.wk.core.web.exception.GeneralException;
import org.wk.upms.common.constant.Constant;
import org.wk.upms.dao.ManagerRoleDao;
import org.wk.upms.dao.ResourceDao;
import org.wk.upms.dao.RoleResourceDao;
import org.wk.upms.domain.ManagerRoleEntity;
import org.wk.upms.domain.ResourceEntity;
import org.wk.upms.domain.RoleResourceEntity;
import org.wk.upms.enums.ResourceType;
import org.wk.upms.view.MenuVo;

import java.util.*;

@Service
public class ResourceServiceImpl implements ResourceService {
    private  Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private ResourceDao resourceDao;

    @Autowired
    private ManagerRoleDao managerRoleDao;

    @Autowired
    private RoleResourceDao roleResourceDao;

    @Override
    public Set<String> queryAllPerms(String userId) {
        List<ResourceEntity> resourceEntities=null;
        if (Constant.SUPER_ADMIN.equals(userId)) {
            resourceEntities = resourceDao.findAll();
        } else {
            List<ManagerRoleEntity> managerRoleEntities = managerRoleDao.findByManagerId(userId);
            List<String> roleIds = new ArrayList<>();
            for (ManagerRoleEntity entity:managerRoleEntities) {
                roleIds.add(entity.getRoleId());
            }
            List<RoleResourceEntity> roleResourceEntities = roleResourceDao.findByRoleIdIn(roleIds);
            List<String> resourceIds = new ArrayList<>();
            for (RoleResourceEntity entity: roleResourceEntities) {
                resourceIds.add(entity.getResourceId());
            }
            resourceEntities = resourceDao.findByIdIn(resourceIds);
        }

        //用户权限列表
        Set<String> permsSet = new HashSet<>();

        if (resourceEntities!=null && !resourceEntities.isEmpty()) {
            for (ResourceEntity resource:resourceEntities) {
                if (Strings.isNullOrEmpty(resource.getPerms()))
                    continue;
                permsSet.addAll(Arrays.asList(resource.getPerms().trim().split(",")));
            }
        }
        return permsSet;
    }

    @Override
    public List<MenuVo> selectMenuByUserId(String userId) {
        //系统管理员，拥有最高权限
        if(Constant.SUPER_ADMIN.equals(userId)){
            return getAllMenuList(null);
        }
        //用户菜单列表
        List<ManagerRoleEntity> managerRoleEntities = managerRoleDao.findByManagerId(userId);

        List<String> roleIds = new ArrayList<>();
        for (ManagerRoleEntity entity:managerRoleEntities) {
            roleIds.add(entity.getRoleId());
        }
        List<RoleResourceEntity> roleResourceEntities = roleResourceDao.findByRoleIdIn(roleIds);

        List<String> menuIdList = new ArrayList<>();
        for (RoleResourceEntity entity:roleResourceEntities) {
            menuIdList.add(entity.getResourceId());
        }
        return getAllMenuList(menuIdList);
    }
    private List<MenuVo> getAllMenuList(List<String> menuIdList){
        //查询根菜单列表
        List<MenuVo> menuList = queryListParentId("0", menuIdList);
        //递归获取子菜单
        getMenuTreeList(menuList, menuIdList);

        return menuList;
    }
    /**
     * 递归
     */
    private List<MenuVo> getMenuTreeList(List<MenuVo> menuList, List<String> menuIdList){
        List<MenuVo> subMenuList = new ArrayList<>();
        for(MenuVo entity : menuList){
            //目录
            if(ResourceType.CATALOG.getCode().equals(entity.getTypeCode())){
                entity.setList(getMenuTreeList(queryListParentId(entity.getMenuId(), menuIdList), menuIdList));
            }
            subMenuList.add(entity);
        }
        return subMenuList;
    }
    /**
     *
     * @param parentId 上级ID
     * @param menuIdList 用户拥有的菜单ID
     * @return
     */
    public List<MenuVo> queryListParentId(String parentId, List<String> menuIdList) {
        List<MenuVo> menuList = queryListParentId(parentId);
        if(menuIdList == null){
            return menuList;
        }

        List<MenuVo> userMenuList = new ArrayList<>();
        for(MenuVo menu : menuList){
            if(menuIdList.contains(menu.getMenuId())){
                userMenuList.add(menu);
            }
        }
        return userMenuList;
    }


    @Override
    public List<MenuVo> selectList(Object o) {
        List<ResourceEntity> resourceEntities = resourceDao.findAll(Sort.by(Sort.Direction.ASC,"sortNo"));
        List<MenuVo> menuVos = new ArrayList<>();
        if (resourceEntities!=null && !resourceEntities.isEmpty()) {
            MenuVo menuVo;
            for (ResourceEntity resourceEntity : resourceEntities) {
                menuVo = new MenuVo();
                BeanUtils.copyProperties(resourceEntity, menuVo);
                menuVo.setMenuId(resourceEntity.getId());
                menuVos.add(menuVo);
            }
        }
        return menuVos;
    }

    @Override
    public MenuVo selectById(String id) {
        ResourceEntity resourceEntity = resourceDao.getOne(id);
        if (resourceEntity==null) {
            throw new GeneralException("菜单不存在");
        }
        MenuVo menuVo = new MenuVo();
        BeanUtils.copyProperties(resourceEntity, menuVo);
        menuVo.setMenuId(resourceEntity.getId());
        return menuVo;
    }

    @Override
    public List<MenuVo> queryNotButtonList() {
        List<ResourceEntity> resourceEntities = resourceDao.findByTypeCodeNotOrderBySortNoAsc(ResourceType.BUTTON.getCode());
        List<MenuVo> menuVos = new ArrayList<>();
        if (resourceEntities!=null && !resourceEntities.isEmpty()) {
            MenuVo menuVo;
            for (ResourceEntity resourceEntity : resourceEntities) {
                menuVo = new MenuVo();
                BeanUtils.copyProperties(resourceEntity, menuVo);
                menuVo.setMenuId(resourceEntity.getId());
                menuVos.add(menuVo);
            }
        }
        //添加顶级菜单
        MenuVo root = new MenuVo();
        root.setMenuId("0");
        root.setName("一级菜单");
        root.setParentId("-1");
        root.setOpen(true);
        menuVos.add(root);
        return menuVos;
    }

    @Override
    public void insert(MenuVo menu) {
        logger.info("保存资源------{}",menu);
        ResourceEntity resourceEntity = new ResourceEntity();
        String parentId = menu.getParentId();
        String parentName=null;
        if (!parentId.equals("0")) {
            Optional<ResourceEntity> opt = resourceDao.findById(parentId);
            if (opt.isPresent()) {
                parentName = opt.get().getParentName();
            } else {
                throw new GeneralException("上级菜单不存在");
            }
        }
        BeanUtils.copyProperties(menu,resourceEntity);
        resourceEntity.setParentName(parentName);
        resourceDao.save(resourceEntity);
    }

    @Override
    public void updateById(MenuVo menu) {
        logger.info("更新资源------{}",menu);
        String id = menu.getMenuId();
        ResourceEntity resourceEntity = resourceDao.getOne(id);
        String parentId = menu.getParentId();
        String parentName=null;
        if (!parentId.equals("0")) {
            Optional<ResourceEntity> opt = resourceDao.findById(parentId);
            if (opt.isPresent()) {
                parentName = opt.get().getParentName();
            } else {
                throw new GeneralException("上级菜单不存在");
            }
        }
        BeanUtils.copyProperties(menu,resourceEntity);
        resourceEntity.setParentName(parentName);
        resourceDao.update(resourceEntity);
    }

    @Override
    public List<MenuVo> queryListParentId(String parentId) {
        List<ResourceEntity> resourceEntities = resourceDao.findByParentId(parentId);
        List<MenuVo> menuVos = new ArrayList<>();
        if (resourceEntities!=null && !resourceEntities.isEmpty()) {
            MenuVo menuVo;
            for (ResourceEntity resourceEntity : resourceEntities) {
                menuVo = new MenuVo();
                BeanUtils.copyProperties(resourceEntity, menuVo);
                menuVo.setMenuId(resourceEntity.getId());
                menuVos.add(menuVo);
            }
        }
        return menuVos;
    }

    @Override
    public void delete(String menuId) {
        resourceDao.deleteById(menuId);
    }


}
